package io.gitee.chearnee.fw.common.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @Author: ning
 * @Date: 2020/12/24 17:45
 * @Description:
 */
public interface IFlagsEnum {

  /**
   * 默认全位值:65535
   */
  int DEFAULT_ALL_FLAG = 65535;

  Integer getBitValue();

//    default boolean hasFlag(IFlagsEnum iFlagsEnum){
//      return  (getValue()&iFlagsEnum.getValue())== iFlagsEnum.getValue();
//    }

  /**
   * 当前枚举值是否在总枚举值中  例如： 2 in 7 ==true
   *
   * @param flags
   * @return
   */
  default boolean in(int flags) {
    return (getBitValue() & flags) != 0;
  }


  /**
   * 将位值或起来
   *
   * @param flags
   * @return
   */
  static int or(int... flags) {
    int flagResult = 0;
    for (int flag : flags) {
      flagResult |= flag;
    }
    return flagResult;
  }

  /**
   * 将位值或起来
   *
   * @param flags
   * @return
   */
  static int or(Iterable<Integer> flags) {
    int flagResult = 0;
    for (int flag : flags) {
      flagResult |= flag;
    }
    return flagResult;
  }
  /**
   * 是否有共有的值 例如：3&6&2=2
   *
   * @param flags
   * @return
   */
  default boolean hadSharedValue(int... flags) {
    int tempFlag = getBitValue();
    for (int flag : flags) {
      tempFlag &= flag;
    }
    return tempFlag > 0;
  }

  /**
   * 枚举值的and
   *
   * @param flag
   * @return
   */
  default int and(int flag) {
    return getBitValue() & flag;
  }

  /**
   * 枚举值的交集值 例如：7&14->[2,4]
   *
   * @param flags
   * @return
   */
  static Collection<Integer> and(int... flags) {
    List<Integer> integers = new ArrayList<>();
    int i = or(flags);
    if (i == 0) {
      return integers;
    }
    return divide(i);
  }


//  /**
//   * 异或某个位值 例如 7^4=3
//   *
//   * @param flags
//   * @return
//   */
//  default int xor(int... flags) {
//    int flagResult = getBitValue();
//    for (int flag : flags) {
//      flagResult ^= flag;
//    }
//    return flagResult;
//  }

  /**
   * 移除某个位值 例如 7&(~4)=3
   *
   * @param flag
   * @return
   */
  default int minus(int flag) {
    return flag & (~getBitValue());
  }

  /**
   * 移除某个位值 例如 7&(~4)=3
   *
   * @param flags
   * @return
   */
  static int minus(int totalBitValue, int... flags) {
    int flagResult = totalBitValue;
    for (int flag : flags) {
      flagResult &= ~flag;
    }
    return flagResult;
  }

  /**
   * 一个总位枚举值可以分成多少个小的枚举值 例如: 总枚举值 7 -> 1,2,4
   *
   * @param flags 总枚举值
   * @return
   */
  static Collection<Integer> divide(int flags) {
    ArrayList<Integer> integers = new ArrayList<>();
    if (flags > 0) {
      int pow = 0;
      do {
        if ((flags & 1) == 1) {
          integers.add((int) Math.pow(2, pow));
        }
        ++pow;
      } while ((flags >>= 1) > 0);
    }
    return integers;
  }
}